package com.education.platform.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.AES;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.education.platform.dto.user.*;
import com.education.platform.entity.User;
import com.education.platform.entity.UserIdentity;
import com.education.platform.entity.UserProfile;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.UserIdentityMapper;
import com.education.platform.mapper.UserMapper;
import com.education.platform.mapper.UserProfileMapper;
import com.education.platform.service.SmsService;
import com.education.platform.service.UserService;
import com.education.platform.common.ResultCode;
import com.education.platform.vo.user.UserIdentityVO;
import com.education.platform.vo.user.UserProfileVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 用户服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final UserProfileMapper userProfileMapper;
    private final UserIdentityMapper userIdentityMapper;
    private final SmsService smsService;

    // 用于身份证号加密的密钥（实际项目中应该从配置文件读取）
    private static final String ID_ENCRYPT_KEY = "education_platform_2024";
    private final AES aes = new AES(ID_ENCRYPT_KEY.getBytes());

    @Override
    public UserProfileVO getMyProfile() {
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 获取用户基本信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 获取用户详细资料
        UserProfile profile = userProfileMapper.selectOne(
            new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, userId));

        // 获取身份认证状态
        UserIdentity identity = userIdentityMapper.selectOne(
            new LambdaQueryWrapper<UserIdentity>().eq(UserIdentity::getUserId, userId));

        UserProfileVO vo = new UserProfileVO();
        vo.setUserId(user.getId());
        vo.setUsername(user.getUsername());
        vo.setMobile(user.getMobile());
        vo.setEmail(user.getEmail());
        vo.setRoles(user.getRoles());
        vo.setAvatarUrl(user.getAvatarUrl());
        vo.setCreatedAt(user.getCreatedAt());

        if (profile != null) {
            vo.setRealName(profile.getRealName());
            vo.setGender(profile.getGender());
            vo.setBirthday(profile.getBirthday());
            vo.setCity(profile.getCity());
            vo.setIntro(profile.getIntro());
            vo.setSubjects(profile.getSubjects());
            vo.setEducation(profile.getEducation());
            vo.setSchool(profile.getSchool());
            vo.setExperienceYears(profile.getExperienceYears());
            vo.setHourlyRate(profile.getHourlyRate());
        }

        if (identity != null) {
            vo.setIdentityStatus(identity.getStatus());
        } else {
            vo.setIdentityStatus("NOT_SUBMITTED");
        }

        return vo;
    }

    @Override
    @Transactional
    public void updateMyProfile(UpdateProfileDTO updateProfileDTO) {
        Long userId = StpUtil.getLoginIdAsLong();

        // 更新用户基本信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        if (StrUtil.isNotBlank(updateProfileDTO.getEmail())) {
            user.setEmail(updateProfileDTO.getEmail());
            userMapper.updateById(user);
        }

        // 更新用户详细资料
        UserProfile profile = userProfileMapper.selectOne(
            new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, userId));

        if (profile == null) {
            profile = new UserProfile();
            profile.setUserId(userId);
        }

        BeanUtils.copyProperties(updateProfileDTO, profile);
        
        if (profile.getId() == null) {
            userProfileMapper.insert(profile);
        } else {
            userProfileMapper.updateById(profile);
        }
    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        // 这里应该实现文件上传到MinIO的逻辑
        // 暂时返回模拟的URL
        String avatarUrl = "http://minio.example.com/avatars/" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
        
        // 更新用户头像URL
        Long userId = StpUtil.getLoginIdAsLong();
        User user = new User();
        user.setId(userId);
        user.setAvatarUrl(avatarUrl);
        userMapper.updateById(user);
        
        log.info("用户{}上传头像成功: {}", userId, avatarUrl);
        return avatarUrl;
    }

    @Override
    @Transactional
    public void submitIdentity(SubmitIdentityDTO submitIdentityDTO) {
        Long userId = StpUtil.getLoginIdAsLong();

        // 检查是否已经提交过
        UserIdentity existingIdentity = userIdentityMapper.selectOne(
            new LambdaQueryWrapper<UserIdentity>().eq(UserIdentity::getUserId, userId));

        UserIdentity identity;
        if (existingIdentity != null && !"REJECTED".equals(existingIdentity.getStatus())) {
            throw new BusinessException("身份认证已提交，请勿重复提交");
        }

        if (existingIdentity != null) {
            // 更新被拒绝的记录
            identity = existingIdentity;
        } else {
            // 创建新记录
            identity = new UserIdentity();
            identity.setUserId(userId);
        }

        // 加密身份证号（如果有）
        if (submitIdentityDTO.getIdNumber() != null && !submitIdentityDTO.getIdNumber().isEmpty()) {
            identity.setIdNumberEnc(aes.encryptHex(submitIdentityDTO.getIdNumber()));
        }
        
        // 设置照片路径（允许为空，教员申请时可能不需要）
        if (submitIdentityDTO.getIdFrontPath() != null && !submitIdentityDTO.getIdFrontPath().isEmpty()) {
            identity.setIdFrontPath(submitIdentityDTO.getIdFrontPath());
        }
        if (submitIdentityDTO.getIdBackPath() != null && !submitIdentityDTO.getIdBackPath().isEmpty()) {
            identity.setIdBackPath(submitIdentityDTO.getIdBackPath());
        }
        if (submitIdentityDTO.getSelfiePath() != null && !submitIdentityDTO.getSelfiePath().isEmpty()) {
            identity.setSelfiePath(submitIdentityDTO.getSelfiePath());
        }
        
        // 设置资质证书
        if (submitIdentityDTO.getCertificates() != null && !submitIdentityDTO.getCertificates().isEmpty()) {
            identity.setCertificates(String.join(",", submitIdentityDTO.getCertificates()));
        }
        
        identity.setStatus("PENDING");
        identity.setSubmittedAt(LocalDateTime.now());

        if (identity.getId() == null) {
            userIdentityMapper.insert(identity);
        } else {
            userIdentityMapper.updateById(identity);
        }

        log.info("用户{}提交身份认证", userId);
    }

    @Override
    public UserIdentityVO getIdentityStatus() {
        Long userId = StpUtil.getLoginIdAsLong();
        
        UserIdentity identity = userIdentityMapper.selectOne(
            new LambdaQueryWrapper<UserIdentity>().eq(UserIdentity::getUserId, userId));

        UserIdentityVO vo = new UserIdentityVO();
        if (identity != null) {
            vo.setStatus(identity.getStatus());
            vo.setAuditNote(identity.getAuditNote());
            vo.setSubmittedAt(identity.getSubmittedAt());
            vo.setAuditedAt(identity.getAuditedAt());
            vo.setIdFrontPath(identity.getIdFrontPath());
            vo.setIdBackPath(identity.getIdBackPath());
            vo.setSelfiePath(identity.getSelfiePath());
            
            if (StrUtil.isNotBlank(identity.getCertificates())) {
                vo.setCertificates(Arrays.asList(identity.getCertificates().split(",")));
            }
        } else {
            vo.setStatus("NOT_SUBMITTED");
        }

        return vo;
    }

    @Override
    @Transactional
    public void bindMobile(BindMobileDTO bindMobileDTO) {
        Long userId = StpUtil.getLoginIdAsLong();

        // 验证验证码
        boolean isValid = smsService.validateCode(bindMobileDTO.getMobile(), bindMobileDTO.getCode(), "BIND_MOBILE");
        if (!isValid) {
            throw new BusinessException(ResultCode.SMS_CODE_INVALID);
        }

        // 检查手机号是否已被其他用户使用
        User existingUser = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getMobile, bindMobileDTO.getMobile())
                .ne(User::getId, userId));
        
        if (existingUser != null) {
            throw new BusinessException("该手机号已被其他用户使用");
        }

        // 更新手机号
        User user = new User();
        user.setId(userId);
        user.setMobile(bindMobileDTO.getMobile());
        userMapper.updateById(user);

        log.info("用户{}绑定手机号成功: {}", userId, bindMobileDTO.getMobile());
    }

    @Override
    public com.education.platform.vo.user.UserStatsVO getUserStats() {
        Long userId = StpUtil.getLoginIdAsLong();
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        com.education.platform.vo.user.UserStatsVO stats = new com.education.platform.vo.user.UserStatsVO();

        // 这里需要根据实际情况从订单表、需求表等查询统计数据
        // 目前返回模拟数据，后续可以优化
        
        boolean isTeacher = user.getRoles().contains("TEACHER");
        
        if (isTeacher) {
            // 教员统计
            stats.setOrderCount(28);
            stats.setCompletedOrderCount(25);
            stats.setInProgressOrderCount(3);
            stats.setPendingOrderCount(0);
            stats.setRating(java.math.BigDecimal.valueOf(4.8));
            stats.setStudentCount(15);
            stats.setEarnings(java.math.BigDecimal.valueOf(3200));
        } else {
            // 家长统计
            stats.setOrderCount(8);
            stats.setCompletedOrderCount(6);
            stats.setInProgressOrderCount(2);
            stats.setPendingOrderCount(0);
            stats.setDemandCount(3);
            stats.setFavoriteCount(12);
            stats.setReviewCount(6);
        }

        return stats;
    }
} 